package de.uhlesoluschns.opensearch.ui;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import android.app.Activity;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.AdapterView.OnItemClickListener;
import de.uhlesoluschns.opensearch.OpenSearch;
import de.uhlesoluschns.opensearch.R;
import de.uhlesoluschns.opensearch.OpenSearch.Provider;
import de.uhlesoluschns.opensearch.OpenSearch.Suggestion;
import de.uhlesoluschns.opensearch.provider.SuggestionsAdapter;

public class SearchBox extends Activity implements OnClickListener,
		OnItemClickListener, DialogInterface.OnClickListener, OnFocusChangeListener, TextWatcher {

	private static final int DIALOG_PROVIDERS = 0;

	public static final String PREF_PROVIDER = "selectedProvider";

	private AutoCompleteTextView searchInput;
	private ImageButton providerButton;
	private ImageButton searchButton;
	private LinearLayout searchBar;

	private int engineId;
	private String engineSearchUrl;
	private String engineInputEncoding;
	private boolean hasSuggestions;

	private SuggestionsAdapter suggestionsAdapter;

	private SharedPreferences prefs;

	private Cursor selectedProvider;
	private Cursor providers;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.search_box);
		providers = managedQuery(Provider.CONTENT_URI, new String[] {
				Provider.COL_ID, Provider.COL_SHORT_NAME, Provider.COL_IMAGE },
				null, null, Provider.COL_SHORT_NAME);
		prefs = PreferenceManager.getDefaultSharedPreferences(this);
		initUI();
		initSearchProvider(getIntent().getData());
		initSearchSuggestions();
	}

	@Override
	protected void onStart() {
		super.onStart();
		if (searchInput != null) {
			searchInput.setText(null);
		}
	}

	private void initUI() {
		// for exiting the app
		searchBar = (LinearLayout) findViewById(R.id.search_bar);
		searchBar.setOnClickListener(this);
		// this one is just to prevent exiting if search_plate is clicked
		findViewById(R.id.search_plate).setOnClickListener(this);

		searchInput = (AutoCompleteTextView) findViewById(R.id.search_src_text);
		searchInput.addTextChangedListener(this);
//		searchInput.setOnItemClickListener(this);
		searchInput.setOnFocusChangeListener(this);

		providerButton = (ImageButton) findViewById(R.id.search_provider);
		providerButton.setOnClickListener(this);
		searchButton = (ImageButton) findViewById(R.id.search_go);
		searchButton.setOnClickListener(this);
	}

	private void initSearchProvider(Uri uri) {
		System.out.println("OpenSearch.initSearchProvider()");
		String id = null;
		if (uri != null) {
			id = uri.getLastPathSegment();
		}

		if (id == null || Provider.PATH.equals(id)) {
			id = "" + prefs.getInt(PREF_PROVIDER, -1);
		}

		selectedProvider = managedQuery(Provider.CONTENT_URI, new String[] {
				Provider.COL_ID, Provider.COL_SHORT_NAME, Provider.COL_IMAGE,
				Provider.COL_SEARCH_URL, Provider.COL_SUGGESTION_URL,
				Provider.COL_INPUT_ENCODING }, Provider.COL_ID + "=?",
				new String[] { id }, null);
		if (selectedProvider.moveToFirst()) {
			engineId = selectedProvider.getInt(0);
			searchInput.setText(null);
			searchInput.setHint(selectedProvider.getString(1));
			byte[] data = selectedProvider.getBlob(2);
			try {
				providerButton.setImageBitmap(BitmapFactory.decodeByteArray(
						data, 0, data.length));
			} catch (Exception e) {
				providerButton.setImageBitmap(null);
			}
			engineSearchUrl = selectedProvider.getString(3);
			hasSuggestions = !selectedProvider.isNull(4);
			engineInputEncoding = selectedProvider.getString(5);
		}
	}

	private void initSearchSuggestions() {
		// attach the suggestions adapter
		suggestionsAdapter = null;
		if (hasSuggestions) {
			suggestionsAdapter = new SuggestionsAdapter(this,
					android.R.layout.simple_dropdown_item_1line, null,
					new String[] { Suggestion.COL_SUGGESTION },
					new int[] { android.R.id.text1 }, engineId);
		}
		searchInput.setAdapter(suggestionsAdapter);
	}

	private void launchSearch() {
		String query = searchInput.getText().toString();
		if (TextUtils.getTrimmedLength(query) < 1) {
			return;
		}
		try {
			query = URLEncoder.encode(query, engineInputEncoding);
		} catch (UnsupportedEncodingException e) {
		}

		Uri searchUri = Uri.parse(String.format(engineSearchUrl, query));
		Intent search = new Intent(Intent.ACTION_VIEW, searchUri);
		search.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		startActivity(search);
		finish();
	}

	private void listProviders() {
		showDialog(DIALOG_PROVIDERS);
	}

	/*
	 * UI Event Listener implementations
	 */
	public void onClick(View v) {
		if (v == searchBar) {
			System.out.println("SearchBox.onClick() :: searchBar");
			finish();
		} else if (v == searchButton) {
			launchSearch();
		} else if (v == providerButton) {
			listProviders();
		}
	}

	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		System.out.println("SearchBox.onItemClick()");
		System.out.println(parent);
		System.out.println(view);
		launchSearch();
	}

	public void onClick(DialogInterface dialog, int which) {
		Editor editor = prefs.edit();
		providers.moveToPosition(which);
		editor.putInt(PREF_PROVIDER, providers.getInt(0));
		editor.commit();
		initSearchProvider(null);
		initSearchSuggestions();
		dialog.dismiss();
	}

	public void onFocusChange(View v, boolean hasFocus) {
		final WindowManager.LayoutParams lp = getWindow().getAttributes();
		if (hasFocus) {
			lp.softInputMode = (lp.softInputMode & ~WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE)
					| WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED;
		} else {
			// noinspection PointlessBitwiseExpression
			lp.softInputMode = (lp.softInputMode & ~WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE)
					| WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED;
		}
		if (v.getWindowToken() != null) {
			final WindowManager manager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
			manager.updateViewLayout(v.getRootView(), lp);

			// if (mShowKeyboard) {
			if (getResources().getConfiguration().hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
				InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
				inputManager.showSoftInput(v, 0);
			}
			// mShowKeyboard = false;
			// }
		}
	}
	
	public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
	
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		 boolean enabled = TextUtils.getTrimmedLength(searchInput.getText()) != 0;
		 searchButton.setEnabled(enabled);
		 searchButton.setFocusable(enabled);
		 searchInput.setListSelection(-1);
	}
	
	public void afterTextChanged(Editable s) {}

	/*
	 * Overrides
	 */
	@Override
	protected Dialog onCreateDialog(int id) {
		Builder builder = new Builder(this);
		switch (id) {
		case DIALOG_PROVIDERS:
			builder.setTitle("Search Providers");
			builder.setCancelable(true);
			providers.requery();
			int selectedId = prefs.getInt(PREF_PROVIDER, -1);
			int which = -1;
			while (providers.moveToNext()) {
				if (selectedId == providers.getInt(0)) {
					which = providers.getPosition();
					break;
				}
			}
			builder.setSingleChoiceItems(providers, which,
					Provider.COL_SHORT_NAME, this);
			break;
		default:
			return null;
		}
		return builder.create();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.search_box_options, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_add_provider:
			Intent intent = new Intent(Intent.ACTION_VIEW,
					OpenSearch.ADD_PROVIDER_URI);
			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			startActivity(intent);
			return true;
		case R.id.menu_delete_provider:
			getContentResolver().delete(Provider.CONTENT_URI,
					Provider.COL_ID + "=?", new String[] { "" + engineId });
			showDialog(DIALOG_PROVIDERS);
			return true;
		case R.id.menu_request_provider:
			startActivity(new Intent(
					Intent.ACTION_DEFAULT,
					Uri.parse("mailto:TimoUhlmann@googlemail.com?subject=OpenSearch%20Provider")));
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

}
